学习 Java 方法后的一些理解与总结

一个 Java 方法是为了执行某个操作的一些语句的组合,本质是一段代码片段。

1
2
3
4
方法定义在类体当中,在一个类当中可以定义多个方法
方法编写的位置没有先后顺序,可以随意
方法体当中不能再定义方法!!!!
方法体由 java 语句构成,方法体当中的代码遵守自上而下的顺序依次执行

创建方法

1
2
3
public static int stuAge(int a){
// method
}
  1. public static:修饰符

    • 可选项,不是必须的
  2. int:返回值类型

    • 返回值类型可以是 Java 任意一种类型,包括基本数据类型和所有的引用数据类型
    • 也可能一个方法执行结束之后不返回任何数据,此时应使用 void 关键字
    • 返回值类型不是 void 的时候,表示这个方法执行结束之后必须返回一个具体的值
    • return 值; //值的数据类型必须和方法的返回值一致,否则编译报错
      eg. 拥有返回值类型的方法,定义方法计算两个 int 类型数据的商
      1
      2
      3
      4
      5
      6
      public static int divide(int a,int b){
      return a / b;
      //已经执行 return 语句即结束当前方法
      //System.out.println("Wihieree");
      //编译报错,因为永远不会执行 sout
      }

    当返回值为空的时候使用 return; 语句是为了结束当前方法

  3. stuAge:方法名

    • 合法的标识符
    • 见名知意
    • 首字母要求小写,后面每个单词首字母大写
      1. stuAge stuName maxNumFuntion
  4. a:形参(形式参数)

    • 可选项,不是必须
    • 形参是局部变量
    • 多个形参之间用 “逗号” 隔开,要求类型对应相同,类型不同的时候要求能够进行相应的自动类型转换
      1. int a,int b,int c
    • 形参中起决定性作用的是形参的数据类型,形参的名字就是局部变量的名字
  5. int a:参数列表

    • 方法再调用的时候,实际给这个方法传递的真实数据被称为:实际参数,简称实参
    • 实参列表和形参列表必须满足
      1. 数量相同
      2. 类型对应相同
        1
        2
        3
        4
        5
        6
        7
        //定义一个 sum 方法
        public static int sum(int a,int b){
        //int a,int b 是形参列表
        }
        //方法调用
        //sum("abc","def"); //编译报错
        sum(10,20);

eg. 定义一个 max() 方法,接受 num1 和 num2 两个参数并返回两者之间的最大值

1
2
3
4
5
6
7
8
9
public static int maxFunt(int num1, int num2) {
int max;
if (num1 > num2) {
max = num1;
}else {
max = num2;
}
return max;
}

方法调用

方法只定义不去调用时不会执行的,只有在调用的时候才会执行

语法规则:

1
2
<方法的修饰符列表当中有 static >
类名.方法名(实参列表);这是一条 java 语句,表示调用某个类的某个方法,传递这样的实参

eg.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//public 表示公开的
//class 表示定义类
// MethodTest03 是一个类名
public class MethodTest03 {
//表示定义一个公开的类 MethodTest03,由于是公开的类,所以源文件名必须为 MethodTest03

//类体
//类体中不能直接编写 java 语句,除声明变量之外
//方法出现在类体当中

//方法
//public 表示公开的
//static 表示静态的
//void 表示方法执行结束之后不返回任何数据
//main 是方法名:主方法
//(String[] args):形式参数列表,其中String[]是一种引用数据类型,args 是一个局部变量的变量名
//以下只有 args 这个局部变量的变量名是随意的
//主方法就需要这样固定编写,这是程序的入口(SUN 规定的,必须这样写)
public static void main(String[] args){

//这里的程序是一定会执行的
//main 方法是 JVM 负责调用的,是一个入口位置
//从这里作为起点开始执行程序
//在这里调用其它方法
//调用 MethodTest03 的 sum 方法,传递两个实参
MethodTest03.sum(10,20); //实参

//一个方法可以被重复使用,重复调用
int a = 300;
MethodTest03.sum(a,500);
}

//自定义方法:不是程序的入口
//方法作用:计算两个 int 类型数据的和,不要求返回结果,但是要求将结果直接输出到控制台
//修饰符列表:public static
//返回值类型:void
//方法名:sum
//形式参数列表:(int x,int y)
//方法体:主要任务是求和之后输出计算结果
public static void sum(int i,int j){//形参
System.out.println(i + " + " + j + " = " + (i + j));
}

}

参数的值传递

在调用函数时参数是必须被传递的,并且他们的次序必须和他们创建时的参数次序是一样的,参数可以通过值或引用来传递
eg. 通过值来传递参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CanShuTest01 {

public static void main(String[] args) {

int i = 10;
add(i);
System.out.println("main -->> " + i); // 10 这里的值是 main 方法里的 i 的值
}

public static void add(int i) {
i++;
System.out.println("add -->> " + i); // 11
}

}

eg. 通过值来传递参数,当传递的是内存地址的时候

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class CanShuTest02 {
public static void main(String[] args) {
User1 u = new User1(20);
add(u);
System.out.println("main -->> " + u.age);//21
//因为这里的 u 指向的 User1 对象的 age 值在 add 方法
//里修改成了 21
}

//User1 u 形参
public static void add(User1 u) {
u.age++;
System.out.println("add -->> " + u.age); //21
}

}

class User1{
//实例变量
int age;
//构造方法
public User1(int i) {
age = i;
}
}

方法重载 overload

当一个方法有两个或者更多的方法,他们的名字一样但是参数不同时,就叫做方法的重载
它与覆盖是不同的,覆盖是指方法具有相同的名字,类型以及参数的个数
方法重载的优点:

  • 程序员调用方法的时候,比较方便,虽然调用的是不同的方法,但是就感觉在调用同一个方法,不需要记忆更多的方法名

方法重载的条件:

  • 在同一个类当中
  • 方法名相同
  • 参数列表不同:数量、顺序、类型不同
  • 方法重载和方法名 + 参数列表有关系
  • 方法重载和返回值类型、修饰符列表无关
    eg. 定义一个计算两个 int 类型、long 类型、double 类型 数据的和的方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class OverloadTest01 {

    public static void main(String[] args){

    System.out.println(sum(1,2)); //3
    System.out.println(sum(1.3,2.5)); //3.8
    System.out.println(sum(10L,20L)); //30
    }

    public static int sum(int a,int b){
    return a + b;
    }

    public static long sum(long a,long b){
    return a + b;
    }

    public static double sum(double a,double b){
    return a + b;
    }
    }

方法递归

方法递归即为方法自身调用自身

1
2
3
a(){
a();
}

递归是很耗费栈内存的,递归算法可以不用的时候尽量别用
递归必须有结束条件,没有结束条件一定会发生栈溢出错误

1
2
3
4
5
6
7
8
9
10
11
12
13
public class RecursionTest01 {
//主方法
public static void main(String[] args){
//调用 doSome 方法
doSome();
}
// doSome 会被重复调用
public static void doSome(){
System.out.println("doSome begin");
doSome();//这行代码不结束,下一行程序是无法运行的
System.out.println("doSome over");
}
}

递归即使有了结束条件,即使结束条件是正确的,也可能会发生栈内存溢出错误,因为递归太深了
主要应用为目录拷贝
eg. 使用递归计算 1~N 的求和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class RecursionTest03 {

public static void main(String[] args){

//1~4 的和
int n = 4;
int retValue = sum(n);
System.out.println(retValue);
}

public static int sum(int n){
// 4 + 3 + 2 + 1
if (n == 1){
return 1;
}
return n + sum(n-1);
}
}

构造方法(构造函数 / 构造器 / Constructor)

构造方法的作用:构造方法存在的意义是通过构造方法的调用,可以创建对象
当一个对象被创建时候,构造方法用来初始化该对象。构造方法和它所在类的名字相同,但构造方法没有返回值
成员变量之实例变量,属于对象级别的变量,这种变量必须先有对象才能有实例变量
实例变量没有手动赋值的时候,系统默认赋值,在构造方法执行过程中完成的赋值

1
2
3
4
5
6
7
8
9
10
构造方法语法结构:
[修饰符列表] 构造方法名(形式参数列表){
构造方法体;
}
//虽然构造方法语法没有返回值类型,但是构造方法执行之后有返回值

普通方法的语法结构:
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}

对于构造方法来说,”返回值类型”不需要指定,并且也不能写 void, 只要写上 void,那么这个方法就是普通方法
通常会使用构造方法给一个类的实例变量赋初值,或者执行其它必要的步骤来创建一个完整的对象
当一个类中没有定义任何构造方法的话,系统默认给该类提供一个无参数的构造方法,这个构造方法被称为缺省构造器
当一个类显示的将构造方法定义出来了,那么系统则不再默认为这个类提供缺省构造器;建议开发中手动的为当前类提供无参数构造方法
构造方法支持重载机制

在 Java 类和对象的封装中进行补充说明

static 关键字

1
2
3
4
5
1. static 译为 静态的
2. static 修饰的方法是静态方法
3. static 修饰的变量是静态变量
4. 所有 static 修饰的元素都称为静态的,都可以使用"类名."的方式访问,
当然也可以用"引用."的方式访问(但是不建议)

方法定义为静态的情况:

1
2
3
1. 方法描述的是动作,当所有的对象执行这个动作的时候,最终产生影响是一样的,那么这个动作已经不再属于某一对象动作了,可以将这个动作提升为类级别的动作,模板级别的动作
2. 静态方法中无法直接访问实例变量和实例方法
3. 大多数方法都定义为实例方法,一般一个行为或者一个动作在发生的时候,都需要对象的参与,但是也有例外,例如:大多数"工具类"中的方法都是静态方法,因为工具类就是方便编程,为了方便方法的调用,自然不需要 new 对象是最好的


 Comments